use serde::{ ser::Error, Deserialize, Serialize };
use serde_json;
use ts_rs::TS;

/// 交易指令数据
#[derive(Serialize, Deserialize, Debug, Clone, TS)]
#[ts(export)]
pub enum TradeOrderData {
    Buy(Buy),
    Sell(Sell),
}

/// 买单自动
#[derive(Serialize, Deserialize, Debug, Clone, Default, TS)]
#[ts(export)]
pub struct Buy {
    /// 证券名称，采自《国信证券》持仓记录详情
    pub security_name: String,
    /// 证券代码，采自《国信证券》持仓记录详情
    pub security_code: String,
    /// 报价方式
    pub pricing_type: PricingType,
    /// 买入价
    pub buy_price: f64,
    /// 买入量
    pub volume: i32,
    /// 描述
    pub desc: String,
    /// 是否自动下单
    pub is_auto: bool,
    /// 止盈止损价,Stop Profit/Loss Price
    pub spl_price: f64,
}

/// 卖单自动
#[derive(Serialize, Deserialize, Debug, Clone, Default, TS)]
#[ts(export)]
pub struct Sell {
    /// 证券名称，采自《国信证券》持仓记录详情
    pub security_name: String,
    /// 证券代码，采自《国信证券》持仓记录详情
    pub security_code: String,
    /// 报价方式
    pub pricing_type: PricingType,
    pub price: f64,
    pub volume: i32,
    pub desc: String,
    pub is_auto: bool,
}

impl TradeOrderData {
    pub fn tname(&self) -> &str {
        match self {
            TradeOrderData::Buy(_) => "Buy",
            TradeOrderData::Sell(_) => "Sell",
        }
    }
    // pub fn serialize(&self) -> Result<String, serde_json::Error> {
    //     let mut map = serde_json::Map::new();
    //     map.insert(
    //         "type".into(),
    //         serde_json::Value::String(format!("com.fuda.trade.model.TradeOrderData.{}", self.tname()))
    //     );

    //     match self {
    //         TradeOrderData::BuyAuto(data) => {
    //             let data_map = serde_json::to_value(data)?;
    //             map.extend(data_map.as_object().unwrap().clone());
    //         }
    //         TradeOrderData::SellAuto(data) => {
    //             let data_map = serde_json::to_value(data)?;
    //             map.extend(data_map.as_object().unwrap().clone());
    //         }
    //         TradeOrderData::BuyManual(data) => {
    //             let data_map = serde_json::to_value(data)?;
    //             map.extend(data_map.as_object().unwrap().clone());
    //         }
    //         TradeOrderData::SellManual(data) => {
    //             let data_map = serde_json::to_value(data)?;
    //             map.extend(data_map.as_object().unwrap().clone());
    //         }
    //     }

    //     serde_json::to_string(&map)
    // }

    // pub fn deserialize(json: &str) -> Result<TradeOrderData, serde_json::Error> {
    //     let value: serde_json::Value = serde_json::from_str(json)?;
    //     let type_str = value["type"]
    //         .as_str()
    //         .ok_or_else(|| serde_json::Error::custom("Missing type field"))?;

    //     match type_str {
    //         "com.fuda.trade.model.TradeOrderData.BuyAuto" => {
    //             let buy_auto_value = value
    //                 .as_object()
    //                 .ok_or_else(|| serde_json::Error::custom("Expected object"))?;
    //             Ok(
    //                 TradeOrderData::BuyAuto(
    //                     serde_json::from_value(serde_json::Value::Object(buy_auto_value.clone()))?
    //                 )
    //             )
    //         }
    //         "com.fuda.trade.model.TradeOrderData.SellAuto" => {
    //             let sell_auto_value = value
    //                 .as_object()
    //                 .ok_or_else(|| serde_json::Error::custom("Expected object"))?;
    //             Ok(
    //                 TradeOrderData::SellAuto(
    //                     serde_json::from_value(serde_json::Value::Object(sell_auto_value.clone()))?
    //                 )
    //             )
    //         }
    //         "com.fuda.trade.model.TradeOrderData.BuyManual" => {
    //             let buy_manual_value = value
    //                 .as_object()
    //                 .ok_or_else(|| serde_json::Error::custom("Expected object"))?;
    //             Ok(
    //                 TradeOrderData::BuyManual(
    //                     serde_json::from_value(serde_json::Value::Object(buy_manual_value.clone()))?
    //                 )
    //             )
    //         }
    //         "com.fuda.trade.model.TradeOrderData.SellManual" => {
    //             let sell_manual_value = value
    //                 .as_object()
    //                 .ok_or_else(|| serde_json::Error::custom("Expected object"))?;
    //             Ok(
    //                 TradeOrderData::SellManual(
    //                     serde_json::from_value(
    //                         serde_json::Value::Object(sell_manual_value.clone())
    //                     )?
    //                 )
    //             )
    //         }
    //         _ => Err(serde_json::Error::custom("Unknown type")),
    //     }
    // }
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default, TS)]
#[ts(export)]
pub enum PricingType {
    #[default]
    Limit,
    Opp,
}

impl PricingType {
    pub fn description(&self) -> &'static str {
        match self {
            PricingType::Limit => "限价委托",
            PricingType::Opp => "对方最优价格",
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use log::debug;

    // #[tokio::test]
    // async fn test_trade_order_data_serde() {
    //     pretty_env_logger::init_timed();
    //     debug!("debug No more records available; exit the loop");
    //     println!("print No more records available; exit the loop");

    //     let buy_auto = TradeOrderData::BuyAuto(BuyAuto {
    //         security_code: "SH.STK.600519".to_string(),
    //         security_name: "贵州茅台".to_string(),
    //         pricing_type: PricingType::Limit,
    //         price: 500.0,
    //         volume: 500,
    //         desc: "Publish1@trade_commands.rs".to_string(),
    //     });

    //     let json = buy_auto.serialize().unwrap();
    //     // {"type":"com.fuda.trade.model.TradeOrderData.BuyAuto","securityName":"贵州茅台","securityCode":"SH.STK.600519","pricingType":"Limit","price":160.8,"volume":100,"desc":"Publish1@TradeOrderDataUnitTest.kt"}
    //     // {"type":"com.fuda.trade.model.TradeOrderData.BuyAuto","securityName":"贵州茅台","securityCode":"SH.STK.600519","pricingType":"Limit","price":500.0,"volume":500,"desc":"New command added"}
    //     println!("serialized json: \n{}", json);

    //     // Deserialize the JSON back into a TradeOrderData
    //     let buy_auto_de: TradeOrderData = TradeOrderData::deserialize(&json).unwrap();

    //     // Check that the deserialized TradeOrderData matches the original
    //     match (buy_auto, buy_auto_de) {
    //         (TradeOrderData::BuyAuto(original), TradeOrderData::BuyAuto(deserialized)) => {
    //             assert_eq!(original.security_code, deserialized.security_code);
    //             assert_eq!(original.security_name, deserialized.security_name);
    //             assert_eq!(original.pricing_type, deserialized.pricing_type);
    //             assert_eq!(original.price, deserialized.price);
    //             assert_eq!(original.volume, deserialized.volume);
    //             assert_eq!(original.desc, deserialized.desc);
    //         }
    //         _ => panic!("Deserialized TradeOrderData does not match the original"),
    //     }
    // }
}
